﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Configuration;
using System.Collections;

namespace Dixon.Jscp
{
    /// <summary>
    /// Configures the DiXon compiler in a Web server environment
    /// capable of running ASP.net, such as Cassini or Microsoft
    /// IIS.
    /// </summary>
    /// <remarks>
    /// The configuration should be placed in the <code>web.config</code> file
    /// under the <code>jsClientPages</code> section
    /// </remarks>
    public class WebConfiguration : Configuration
    {
        /// <summary>
        /// The default content type used for scripts
        /// </summary>
        const string DefaultScriptContentType = "text/javascript";

        /// <summary>
        /// The default path to the DiXon compiler stylesheet
        /// </summary>
        const string DefaultCompilerStyleSheet = "DiXon/DiXon.xslt";

        /// <summary>
        /// The default path to the source code of JavaScript client pages
        /// </summary>
        const string DefaultSourcePagePath = "jscp";

        /// <summary>
        /// The default path to the compiled pages.
        /// </summary>
        const string DefaultCompiledPagePath = "jscp/Compiled";

        /// <summary>
        /// The HTTP context for which this configuration was created
        /// </summary>
        public HttpContext Context { get; private set; }

        /// <summary>
        /// The original configuration section, represented as a
        /// dictionary
        /// </summary>
        public IDictionary<string, string> Configuration { get; set; }

        /// <summary>
        /// Creates a page configuration instance for the
        /// specified HTTP context
        /// </summary>
        /// <param name="context"></param>
        public WebConfiguration(HttpContext context)
        {
            Context = context;
            // Convert the legacy dictionary to its genericized equivalent
            var configurationMap = 
                ConfigurationManager.GetSection(ConfigurationKey.JsClientPages)
                as IDictionary;

            Configuration = (from DictionaryEntry entry in configurationMap select entry)
                .ToDictionary(
                    entry => entry.Key as string,
                    entry => entry.Value as string
                );
           
        }

        /// <summary>
        /// The path to source pages, as determined by web.config
        /// </summary>
        public override string SourcePagePath
        {
            get 
            {
                return GetConfigurationPath(
                    ConfigurationKey.SourcePagePath, 
                    DefaultSourcePagePath);
            }
        }

        /// <summary>
        /// The path to compiled pages, as determined by
        /// web.config
        /// </summary>
        public override string CompiledPagePath
        {
            get 
            {
                return GetConfigurationPath(
                    ConfigurationKey.CompiledPagePath,
                    DefaultCompiledPagePath);
            }
        }

        /// <summary>
        /// The path to the compiler stylesheet
        /// </summary>
        public override string CompilerStylesheetPath
        {
            get 
            {
                return GetConfigurationPath(
                    ConfigurationKey.CompilerStylesheet,
                    DefaultCompilerStyleSheet);
            }
        }

        /// <summary>
        /// The content type used for scripts
        /// </summary>
        public override string ScriptContentType
        {
            get 
            {
                return GetConfigurationValue(
                    ConfigurationKey.ScriptContentType,
                    DefaultScriptContentType
                    );
            }
        }

        private string GetConfigurationValue(string key, string defaultValue)
        {
            string value;
            if (Configuration.ContainsKey(key))
            {
                value = Configuration[key];
            }
            else
            {
                value = defaultValue;
            }

            return value;
        }

        private string GetConfigurationPath(string key, string defaultValue)
        {
            return Context.Server.MapPath(
                    GetConfigurationValue(key, defaultValue));
        }
    }
}
